local assets =
{
    -- Asset("ANIM", "anim/panda_fisherman_supply_pack.zip"),
    Asset( "IMAGE", "images/map_icons/npc_item_treasure_map.tex" ),  -- 背包贴图
    Asset( "ATLAS", "images/map_icons/npc_item_treasure_map.xml" ),
}
local function GetStringsTable()
    return TUNING.NPC_CHAT_TABLE[ type(TUNING.__NPC_LANGUAGE)=="function" and TUNING.__NPC_LANGUAGE() or TUNING.__NPC_LANGUAGE ] ["npc_event_treasure_map"] or {}
end
local function fn_mark()
    local inst = CreateEntity()
    inst.entity:AddTransform()
	inst.entity:AddNetwork()
	inst.entity:AddMiniMapEntity()

	inst.MiniMapEntity:SetIcon("messagebottletreasure_marker.png")   --- 地图上的红叉

	inst:AddTag("FX")        
    inst:AddTag("INLIMBO")
    inst:AddTag("NOCLICK")
    inst.entity:SetPristine()    
    if not TheWorld.ismastersim then
        return inst
    end
    inst:DoTaskInTime(0,function()
        if inst.Ready ~= true  then
            inst:Remove()   
        end
    end)
    return inst
end
-----------------------------------------------------------------------------------------------
------------- 
----- 背包控制相关
local function container_Widget_change(theContainer)
    local params = {}
    params._theContainerWidget =
    {
        widget =
        {
            slotpos = {},
            animbank = "ui_woby_3x3",
            animbuild = "ui_woby_3x3",
            pos = Vector3(0, 200, 0),
            side_align_tip = 160,
        },
        type = "chest",
        acceptsstacks = true,
        -- usespecificslotsforitems = true,
        -- type = "none",
    }

    for y = 2, 0, -1 do
        for x = 0, 2 do
            table.insert(params._theContainerWidget.widget.slotpos, Vector3(75 * x - 75 * 2 + 75, 75 * y - 75 * 2 + 75, 0))
        end
    end
    function params._theContainerWidget.itemtestfn(container, item, slot)
        if item:HasOneOfTags({"treasure_map","nosteal","irreplaceable"}) then
            return false
        end
        if item.prefab == "npc_item_treasure_map" then
            return false
        end
        return true
    end
    
    theContainer:WidgetSetup("wobysmall",params._theContainerWidget)
    -- if TheWorld.ismastersim then
    --     theContainer:SetNumSlots(#params._theContainerWidget.widget.slotpos)
    -- end
end

local function add_container_before_not_ismastersim_return(inst)
	-------------------------------------------------------------------------------------------------
    ------ 添加背包container组件
    --    local container_WidgetSetup = "wobysmall"
    if TheWorld.ismastersim then
        inst:AddComponent("container")
        inst.components.container.openlimit = 1  ---- 限制1个人打开
    --    inst.components.container:WidgetSetup(container_WidgetSetup)
        container_Widget_change(inst.components.container)
		-- inst.components.container.numslots = 9 -- 格子数 -- 不能用这个，会造成bug
    else
        inst:DoTaskInTime(0.1, function()
            if inst.replica then
                if inst.replica.container then
                --    inst.replica.container:WidgetSetup(container_WidgetSetup)
                container_Widget_change(inst.replica.container)
                end
            end

        end)
    end
    -------------------------------------------------------------------------------------------------
end
-----------------------------------------------------------------------------------------------


local function add_treasure_to_box(inst)
    print("info : add_treasure_to_box")
    local weapon_name = inst.npc_base_lib:GetRandom(inst.npc_base_lib:Get_Equipments_Hand() )
    inst.npc_base_lib:GiveItemByName(weapon_name,1)


    local Base_Material_name = inst.npc_base_lib:GetRandom(inst.npc_base_lib:Get_Base_Materials() )

    -----------------------------------------------------------------------------------------------------
    local stack_max_num = inst.npc_base_lib:Get_Item_Stack_Max_Num(Base_Material_name)
    if stack_max_num and stack_max_num > 70 then    ---- 打了巨量叠堆MOD的人反而得到更少
        stack_max_num = 10
    end

    if TUNING.NPC_CONFIG.REWARDS_LESS == true then
        inst.npc_base_lib:GiveItemByName(Base_Material_name,math.ceil(stack_max_num/2))
    else
        inst.npc_base_lib:GiveItemByName(Base_Material_name,stack_max_num)
    end
    -----------------------------------------------------------------------------------------------------
    local Special_Materials_name = inst.npc_base_lib:GetRandom(inst.npc_base_lib:Get_Special_Materials() )

    stack_max_num = inst.npc_base_lib:Get_Item_Stack_Max_Num(Special_Materials_name)
    if TUNING.NPC_CONFIG.REWARDS_LESS == true then
        inst.npc_base_lib:GiveItemByName(Special_Materials_name,math.ceil(stack_max_num/4))
    else
        inst.npc_base_lib:GiveItemByName(Special_Materials_name,math.ceil(stack_max_num/2))
    end
    -----------------------------------------------------------------------------------------------------
end

local function monster_event_start(inst)
    print("info : monster_event_start")
    local points = inst.npc_base_lib:GetSurroundPoints({
        target = inst,
        range = 8,
        num = 10
    })

    TheSim:LoadPrefabs({ "quagmire_swampig" })  ---- 改外观
    local function Spawn_Pigman_In_Point(pt)
        local pigman = SpawnPrefab("pigguard")
        pigman.AnimState:SetBank("pigman")
        pigman.AnimState:SetBuild("quagmire_swampig_build") 
        pigman.AnimState:PlayAnimation("idle_loop", true)
        -- pigman.AnimState:OverrideSymbol("swap_hat", "quagmire_swampig", "swap_hat")
        -- pigman.AnimState:ShowSymbol("swap_hat")

        pigman.AnimState:Show("HAT")
        pigman.AnimState:Show("HAIR_HAT")
        pigman.AnimState:Hide("HAIR_NOHAT")
        pigman.AnimState:Hide("HAIR")


        pigman.Transform:SetPosition(pt.x,0,pt.z)
        pigman.components.werebeast:SetOnWereFn(function() print("--------")  end)  ---- 不会变身
        pigman.__attack_fn = function()
            if not pigman:IsValid() then
                if pigman.__attack_fn then
                    pigman.__attack_fn:Cancel()
                end
                return
            end

            -- local tar_player = TheSim:FindFirstEntityWithTag("player")
            local tar_player = pigman:GetNearestPlayer(true)
            if tar_player and tar_player:IsValid() and tar_player.components.playercontroller and not tar_player:HasTag("playerghost")  then
                pigman.components.combat:SetTarget(tar_player)
            else
                local point = Vector3( pigman.Transform:GetWorldPosition() )
                local ents = TheSim:FindEntities(point.x, 0, point.z, 40, {"player","npc_tag.isplayer"}, {"playerghost","isdead","INLIMBO","notarget","noattack"}, nil)
                if #ents > 0 then
                            for k, v in pairs(ents) do
                                if v and v:IsValid() then
                                    pigman.components.combat:SetTarget(v)
                                    break
                                end
                            end
                end
                
            end

        end
        pigman:DoPeriodicTask(1,pigman.__attack_fn)

        return pigman
    end

    for i, pt in ipairs(points) do
        local pigman = Spawn_Pigman_In_Point(pt)
        SpawnPrefab("npc_fx_spawn"):PushEvent("Set",{pt = pt})
    end



end
-----------------------------------------------------------------------------------------------
local function treasure_map_nearby_check(inst)
    local theMap = TheSim:FindFirstEntityWithTag(inst.npc_everything_data:Get("Map_ID")) 
    if theMap == nil then
        return
    end
    local dis = inst.npc_base_lib:Distance_Targets(theMap,inst)

    if dis < 30 then -----------------------------------------------------------------------------------
        if inst.light_up_task_flag ~= true then
            inst.light_up_task_flag = true
            inst.light_up_fire = {}
            local points = inst.npc_base_lib:GetSurroundPoints({
                target = Vector3(0,0,0),
                range = 5,
                num = 15
            })
            for i, pt in ipairs(points) do
                local fire = inst:SpawnChild("npc_fx_fire")
                fire:PushEvent("Set",{
                    pt = pt,
                    color = Vector3(255,0,0),
                    a = 0.5,
                    MultColour_Flag = true,
                    light_off = true,
                })
                fire:Hide()
                table.insert(inst.light_up_fire,fire)
                fire:DoTaskInTime(i*0.2,function()
                    fire:Show()
                    fire:PushEvent("light_on")                    
                end)
            end
        end
        inst:Show()

    else    -----------------------------------------------------------------------------------
        inst:Hide()
        inst.light_up_task_flag = false
        if inst.light_up_fire then
            for k, v in pairs(inst.light_up_fire) do
                v:Remove()
            end
            inst.light_up_fire = nil
        end
    end   -----------------------------------------------------------------------------------

end
-----------------------------------------------------------------------------------------------
local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
	inst.entity:AddNetwork()
	inst.entity:AddMiniMapEntity()
    inst.entity:AddAnimState()

    TheSim:LoadPrefabs({ "quagmire_crate" })    ----- 暴食里的物品都得用这个加载素材

    inst.AnimState:SetBank("quagmire_crate")
    inst.AnimState:SetBuild("quagmire_crate")
    inst.AnimState:PlayAnimation("idle",false)

	-- inst.MiniMapEntity:SetIcon("messagebottletreasure_marker.png")   --- 地图上的红叉

	inst:AddTag("irreplaceable")        ---- 不给带出当前世界
	inst:AddTag("nonpotatable")         ---- 不会腐烂？！     

    MakeObstaclePhysics(inst, .75)

    inst.entity:SetPristine()
    -- inst:DoTaskInTime(0,inst.Hide)
    add_container_before_not_ismastersim_return(inst)
    if not TheWorld.ismastersim then
        return inst
    end
    inst:AddComponent("npc_base_lib")
    inst:AddComponent("npc_everything_data")


    inst:AddComponent("inspectable") --可检查组件   
    inst:AddComponent("named")
    -- inst.components.named:SetName(tostring(_table.Name))
    inst.components.named:SetName(GetStringsTable().box_name)
    STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_treasure_box")] = GetStringsTable().inspect_str_box  --人物检查的描述
    -----------------------------------------------------------------------------------------------------------------------------------------------
    inst:DoTaskInTime(0,function()
        if inst.npc_everything_data:Get("Map_ID") == nil then
            inst:Remove()   ----- 没ID的箱子删除
        else
            inst:Hide()
            inst:AddTag("box_"..inst.npc_everything_data:Get("Map_ID"))
        end
    end)

    -----------------------------------------------------------------------------------------------------------------------------------------------
    inst:ListenForEvent("Show_Mark",function()  --------------------- 地图上的标记
        if inst.__mark ~= nil then
            inst.__mark:Remove()
        end
        local mark = SpawnPrefab("npc_item_treasure_box_mark")
        mark.Ready = true
        mark.Transform:SetPosition(inst.Transform:GetWorldPosition())
        inst.__mark = mark     
        inst.npc_base_lib:Add2Child(mark)   
    end)

    inst:ListenForEvent("Hide_Mark",function()
        if inst.__mark ~= nil then
            inst.__mark:Remove()
            inst.__mark = nil
        end
    end)
    -----------------------------------------------------------------------------------------------------------------------------------------------
    --------- 测试用的func
        -- inst:ListenForEvent("onopen",function() 
        --     inst.components.container:Close()
        --     inst.AnimState:PlayAnimation("unwrap")
        --     inst:ListenForEvent("animover",function()
        --         print("++++++++++++++++++++++++++++++++++++++++++++")
        --         inst:Remove()
        --     end)
        -- end)

    inst:ListenForEvent("onopen",function() --- 打开箱子瞬间 删除藏宝图
        local map_id = inst.npc_everything_data:Get("Map_ID")
        if map_id then
            local theMap = TheSim:FindFirstEntityWithTag(map_id) 
            if theMap then
                theMap:Remove()
            else
                print("treasure map remove error")
            end
        end
    end)

    inst:ListenForEvent("onopen",function()
        local monster_prop = 20 --- 20% 概率 是 怪物事件
        if inst.npc_base_lib:Get_Item_Stack_Max_Num("log") > 70 then
            monster_prop = 50   --- 如果用了叠堆MOD超过70个叠堆上限，概率增加
        end
        if math.random(1000)/10 < monster_prop then  
            inst:ListenForEvent("animover",function()
                monster_event_start(inst)
                inst.npc_base_lib:Wisper(GetStringsTable().monster)
            end)
            inst.components.container:Close()
        else
            add_treasure_to_box(inst)
        end
    end)


    inst:ListenForEvent("onclose",function()
        inst.components.container:DropEverything()
        inst.AnimState:PlayAnimation("unwrap")
        inst:ListenForEvent("animover",inst.Remove)
    end)
    -----------------------------------------------------------------------------------------------------------------------------------------------
    
    inst:DoPeriodicTask(5,treasure_map_nearby_check)

    -----------------------------------------------------------------------------------------------------------------------------------------------
    return inst
end

return Prefab("npc_item_treasure_box", fn,assets),
        Prefab("npc_item_treasure_box_mark", fn_mark)